<template>
  <el-form
    ref="form"
    :model="modelValue"
    :inline="inline"
    :label-position="labelPosition"
    :label-width="labelWidth"
    :size="size"
  >
    <component :is="layout_" v-model="value" :fields="fields" v-bind="$attrs" />
    <slot></slot>
    <epx-toolbar v-if="toolbar !== false" :items="toolbar_">
      <el-button v-if="submit !== false" @click="onSubmit">提交</el-button>
      <el-button v-if="reset !== false" @click="onReset">{{ reset }}</el-button>
      <slot name="toolbar"></slot>
    </epx-toolbar>
  </el-form>
</template>

<script lang="ts" setup>
  import { computed, ref, Ref } from 'vue';
  import type { Component } from 'vue';
  import { FormLayoutType, getLayout } from './layouts';
  import EpxToolbar from '../button/EpxToolbar.vue';
  import { Toolbar } from '../button/button';
  import { Row, Size } from '../elementUI';
  import { FormInstance } from 'element-plus';
  import { Field } from './form';

  /**
   * v-model, fields
   */
  const props = withDefaults(
    defineProps<{
      layout?: FormLayoutType;
      fields?: Array<Field>;
      toolbar?: Toolbar['items'] | false;
      modelValue: Row;
      reset?: string | false;
      submit?: string | false;
      inline?: boolean;
      labelWidth?: string;
      labelPosition?: string;
      size?: Size;
      disabled?: boolean;
    }>(),
    {
      modelValue: () => ({}),
      layout: 'Rowed',
      fields: () => [] as Array<Field>,
      reset: '重置',
      submit: '',
      toolbar: undefined,
      inline: false,
      labelWidth: undefined,
      labelPosition: undefined,
      size: undefined,
      disabled: false
    }
  );

  const emit = defineEmits(['update:model-value', 'submit']);

  const layout_ = computed<Component>(() => getLayout(props.layout));
  const toolbar_ = ref<Toolbar['items']>(props.toolbar || []);

  const value = computed<Row>({
    get: () => props.modelValue,
    set: (v) => emit('update:model-value', v)
  });

  const form: Ref<FormInstance | undefined> = ref();

  const onSubmit = async () => {
    if (!form.value) return;

    await form.value.validate(async (valid) => {
      if (valid) {
        emit('submit');
      } else {
        return;
      }
    });
  };

  const onReset = () => {
    if (!form.value) return;
    form.value.resetFields();
  };
</script>

<script lang="ts">
  // 声明额外的选项
  // noinspection JSUnusedGlobalSymbols
  export default {
    inheritAttrs: false
  };
</script>

<style scoped></style>
